<template>
    <div class="imgeditor">
<!--        <input type="file" @change="inputChange">-->
        <div class="editorView">
            <VuePictureCut
                :src="imgsrc"
                @on-change="cutChange"
                ref="pictureCut"
                :msk-option="mskOption"
                :menu-thickness="0"
            >
            </VuePictureCut>
            <canvas id="myCanvasa" :width="canvasWidth" :height="canvasHeight" v-if="mycanvas"></canvas>
            <img :src="markImg" v-if="markImg!=''" id="markImg" :style="{top:markImgPosiy+'px',left:markImgPosix+'px',width:markImgWidth+'px'}" alt="">
            <span v-if="markText!=''" id="markText" :style="{color:markColor,top:markPosiY+'px',left:markPosiX+'px',fontSize:markFontsize+'px',width:markTextWidth+'px',lineHeight:markTextLineHeight+'px'}" class="markTextView">{{markText}}</span>
        </div>
        <el-tabs type="border-card" v-model="activeTab" @tab-click="tabActiveChanged"
                 style="width: 350px;margin-left: 20px" tab-position="left">
            <el-tab-pane label="旋转">
                <div class="toolsItem">
                    <el-button type="primary" @click="rotateRight">右转90度</el-button>
                    <el-button type="primary" @click="rotateLeft">左转90度</el-button>
                </div>
                <div class="toolsItem">
                    <el-button type="primary" @click="flipY">垂直翻转</el-button>
                    <el-button type="primary" @click="flipX">水平翻转</el-button>
                </div>
            </el-tab-pane>
            <el-tab-pane label="裁剪">
                <div class="toolsItem">
                    <el-radio-group v-model="cropShape">
                        <el-radio label="rect" border>矩形</el-radio>
                        <el-radio label="round" border>圆形</el-radio>
                    </el-radio-group>
                </div>
                <div class="toolsItem">
                    <el-radio-group v-model="ratio">
                        <el-radio style="margin-bottom: 5px" label="1-1" border>1:1</el-radio>
                        <el-radio style="margin-bottom: 5px" label="4-3" border>4:3</el-radio>
                        <el-radio style="margin-bottom: 5px" label="3-4" border>3:4</el-radio>
                        <el-radio style="margin-bottom: 5px" label="16-9" border>16:9</el-radio>
                        <el-radio style="margin-bottom: 5px" label="9-16" border>9:16</el-radio>
                        <el-radio style="margin-bottom: 5px" label="3-2" border>3:2</el-radio>
                        <el-radio style="margin-bottom: 5px" label="2-3" border>2:3</el-radio>
                    </el-radio-group>
                </div>
            </el-tab-pane>
            <el-tab-pane label="文字">
                <div class="imgstools">
                    <div class="toolsItem">
                        <span>颜色：</span>
                        <el-color-picker v-model="markColor"></el-color-picker>
                    </div>
                    <div class="toolsItem">
                        <span>文字：</span>
                        <el-input type="textarea" style="flex: 1;width: 142px" v-model="markText" placeholder="placeholder"></el-input>
                    </div>
                    <div class="toolsItem">
                        <span>X轴位置：</span>
                        <el-slider :min='minX' :max="maxX" style="flex: 1" v-model="markPosiX"></el-slider>
                    </div>
                    <div class="toolsItem">
                        <span>Y轴位置：</span>
                        <el-slider :min='minY' :max="maxY" style="flex: 1" v-model="markPosiY"></el-slider>
                    </div>
                    <div class="toolsItem">
                        <span>字体大小：</span>
                        <el-slider :min=0 :max="100" style="flex: 1" v-model="markFontsize"></el-slider>
                    </div>
                    <div class="toolsItem">
                        <span>字体行高：</span>
                        <el-slider  style="flex: 1" v-model="markTextLineHeight"></el-slider>
                    </div>
                    <div class="toolsItem">
                        <span>宽度：</span>
                        <el-slider :min=0 :max="600" style="flex: 1" v-model="markTextWidth"></el-slider>
<!--                        <el-input-number v-model="markTextWidth" style="width: 142px;" :min="0" :max="600"></el-input-number>-->
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="水印">
                <el-upload
                    action=""
                    :auto-upload='false'
                    :limit='1'
                    :multiple='false'
                    class="avatar-uploader"
                    :show-file-list="true"
                    :on-change="beforeAvatarUpload"
                >
                    <img v-if="markImg" :src="markImg" class="avatar">
                    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                </el-upload>
                <div class="toolsItem">
                    <span>X轴位置：</span>
                    <el-slider :min='minX' :max="maxX" style="flex: 1" v-model="markImgPosix"></el-slider>
                </div>
                <div class="toolsItem">
                    <span>Y轴位置：</span>
                    <el-slider :min='minY' :max="maxY" style="flex: 1" v-model="markImgPosiy"></el-slider>
                </div>
<!--                <div class="toolsItem">-->
<!--                    <span>纵横比：</span>-->
<!--                    <el-slider :min='minY' :max="maxY" style="flex: 1" v-model="markImgAutoScle"></el-slider>-->
<!--                </div>-->
                <div class="toolsItem">
                    <span>宽度：</span>
                    <el-slider :min='minY' :max="maxY" style="flex: 1" v-model="markImgWidth"></el-slider>
                </div>
            </el-tab-pane>
<!--            <el-tab-pane label="马赛克">马赛克</el-tab-pane>-->
        </el-tabs>
        <el-button @click="getCustomCanvas">裁剪</el-button>
        <img :src="cutimgsrc"  id="cutimgcanvas" alt="">
<!--        <img :src="cutimgsrc"  id="cutimgcanvas" style="opacity: 0;z-index: -1;position: relative" alt="">-->
    </div>
</template>

<script>
  import {
    VuePictureCut,
    VuePictureCutMask,
    VuePictureCutMenu,
    Bezier,
    createAnimation,
    Tool,
    createUtils
  } from 'vue-picture-cut';

  export default {
    name: 'imgeditor',
    data() {
      return {
        markImg: '',
        canvasHeight:500,
        canvasWidth:600,
        cutCanvasEle:null,
        mycanvas: false,
        cutimgsrc: '',
        rotateControl: true,
        menuHeight: 50,
        activeTab: '',
        cropShape: 'rect',
        ratio: '1-1',
        mskOption: {
          width: 1,
          height: 1,
          isRound: false,
          resize: true
        },
        // imgsrc: '',
        imgsrc: '',
        markText: '',
        markColor: '#000000',
        markPosiX: 0,
        markPosiY: 0,
        markTextWidth:50,
        markFontsize:12,
        markTextLineHeight:20,
        markImgPosix:0,
        markImgPosiy:0,
        markImgWidth:100,
        markImgHeight:'auto',
        markImgAutoScle:true,
        utils: null,
        cropResult: '',
        takeImgSrc: '/logo.png',
        minX:0,
        minY:0,
        maxX:600,
        maxY:500
      }
    },
    computed:{

    },
    watch: {
      cropShape(newValue, oldValue) {
        newValue === 'round' ? this.utils.setMaskRound(true) : this.utils.setMaskRound(false)

      },
      ratio(newValue, oldValue) {
        const ratioarr = newValue.split('-')
        this.utils.setMaskSize(ratioarr[0], ratioarr[1])
      },
      activeTab(newValue, oldValue) {
        const active = newValue
        // const randowmNum=Math.ceil(Math.random()*10000);
        if (active > 1&&oldValue<2) {
          const imgdata64=this.cropImg()
          this.cutimgsrc = imgdata64
          var myFile = this.dataURLtoFile(imgdata64, 'testimg');
          this.imgsrc = URL.createObjectURL(myFile)
          this.mycanvas=true;
          this.$nextTick(()=>{
            this.initOwnerCanvas()
            this.initSlideDatas()
          })
        }else
        if(active<1&&oldValue>1){
          if(this.cutimgsrc==''){
            return
          }
          var myFile = this.dataURLtoFile(this.cutimgsrc, 'testimg');
          this.imgsrc = URL.createObjectURL(myFile)
          this.mycanvas=false
        }
        // if(oldValue==2){
        //   this.drawMarkText()
        // }
        // if (active > 1) {
        //   this.cropImg()
        // }
      },
      markText(){
        this.$nextTick(()=>{
          this.initSlideDatas()
        })
      },
      markImg(){
        this.$nextTick(()=>{
          this.initSlideDatas()
        })
      }
    },
    components: {
      VuePictureCut,
      VuePictureCutMenu
    },
    mounted() {
      const _this=this;
      Tool.loadImg(this.takeImgSrc)
          .then(image => {
            // 加载图片成功
            // image为Image对象
            _this.getImgToBase64(image.src, function (data) {
              var myFile = _this.dataURLtoFile(data, 'testimg');
              _this.imgsrc = URL.createObjectURL(myFile)
            });
          }, () => {
            // 加载图片失败
          });
      this.utils = createUtils(this.$refs['pictureCut']);
    },
    methods: {
      beforeAvatarUpload(file) {
        let filenametype=file.name.split('.');
        filenametype=filenametype[filenametype.length-1]
        if(filenametype!='jpg'&&filenametype!='png'){
          this.$message.error('只能选择JPG或者PNG格式!');
          return false
        }else{
          this.markImg = URL.createObjectURL(file.raw);
          return true
        }
      },
      getCustomCanvas(){
        const _this=this
        let c=document.createElement('canvas');
        const imageele=document.getElementById('cutimgcanvas');
        const imgwidth = imageele.width;
        const imgheight = imageele.height;
        const markImg=document.getElementById('markImg')
        c.width=imgwidth
        c.height=imgheight
        var ctx=c.getContext("2d");
        const cw=this.canvasWidth;
        const ch=this.canvasHeight;
        ctx.drawImage(imageele,0,0,imgwidth,imgheight)
        if(this.markText!=''){
          console.log(ctx.measureText(this.markText))
          const textEleStyle=document.getElementById('markText').getBoundingClientRect();
         ctx.textBaseline ='hanging';
         ctx.font=`${this.markFontsize}px 微软雅黑`

         ctx.fillStyle = this.markColor;
         ctx.textAlign ='left';
         this.canvasTextAutoLine(this.markText,ctx,(this.markPosiX-(cw/2-imgwidth/2)),this.markPosiY-(ch/2-imgheight/2),this.markTextLineHeight,this.markTextWidth)
          // this.owenrDrawText(this.markText,(this.markPosiX-(cw/2-imgwidth/2)),this.markPosiY-(ch/2-imgheight/2),this.markTextWidth,ctx)
          // ctx.fillText(this.markText,(this.markPosiX-(cw/2-imgwidth/2)),this.markPosiY-(ch/2-imgheight/2));
          // this.markText='';
        }
       if(this.markImg!=''){
         ctx.drawImage(markImg,this.markImgPosix-(cw/2-imgwidth/2),this.markImgPosiy-(ch/2-imgheight/2),markImg.width,markImg.height)
       }
        const dataURL = c.toDataURL('image/png');
        this.cutimgsrc=dataURL
        this.getImgToBase64(this.cutimgsrc, function (data) {
          var myFile = _this.dataURLtoFile(data, 'testimg');
          _this.imgsrc = URL.createObjectURL(myFile)
        });
      },
      canvasTextAutoLine(str,ctx,initX,initY,lineHeight,marktextWidth){
        // var ctx = canvas.getContext("2d");
        var lineWidth = 0;
        var canvasWidth = marktextWidth;
        var lastSubStrIndex= 0;
        for(let i=0;i<str.length;i++){
          lineWidth+=ctx.measureText(str[i]).width;
          if(lineWidth>canvasWidth-initX){//减去initX,防止边界出现的问题
            ctx.fillText(str.substring(lastSubStrIndex,i),initX,initY);
            initY+=lineHeight;
            lineWidth=0;
            lastSubStrIndex=i;
          }
          if(i==str.length-1){
            ctx.fillText(str.substring(lastSubStrIndex,i+1),initX,initY);
          }
        }
      },
      owenrDrawText(t,x,y,w,context){
        var chr = t.split("");
        var temp = "";
        var row = [];

        context.font = "20px Arial";
        context.fillStyle = "black";
        context.textBaseline = "middle";

        for(var a = 0; a < chr.length; a++){
          if( context.measureText(temp).width < w ){
            ;
          }
          else{
            row.push(temp);
            temp = "";
          }
          temp += chr[a];
        }

        row.push(temp);

        for(var b = 0; b < row.length; b++){
          context.fillText(row[b],x,y+(b+1)*20);
        }
      },
      initOwnerCanvas(){
        const cs=document.getElementById('myCanvasa');
        const cx = cs.getContext('2d');
        const cw=this.canvasWidth;
        const ch=this.canvasHeight;
        const imageele=document.getElementById('cutimgcanvas');
        imageele.src=this.cutimgsrc
        imageele.onload=function(){
          const nawidth = imageele.naturalWidth;
          const naheight = imageele.naturalHeight;
          if(nawidth>naheight){
            imageele.style.width=cw+'px'
            imageele.style.height=naheight*(cw/nawidth)+'px'
          }else{
            imageele.style.width='auto'
            imageele.style.height=ch+'px'
          }
          const imgwidth = imageele.width;
          const imgheight = imageele.height;
          cx.drawImage(imageele, (cw/2-imgwidth/2), (ch/2-imgheight/2),imgwidth,imgheight);
        }

      },
      tabActiveChanged(tab) {

      },
      inputChange(e) {
        const file = e.target.files[0];
        this.imgsrc = URL.createObjectURL(file);
      },
      cropImg() {
        var result = this.utils.cut({
          encoderOptions: 0.8,
          format: 'image/jpeg'
        })
        return result.src
      },
      initSlideDatas(){
        const _this=this;
        setTimeout(function(){
          const cutele=document.getElementById('cutimgcanvas');
          const cw=_this.canvasWidth;
          const ch=_this.canvasHeight;
          const imgwidth = cutele.width;
          const imgheight = cutele.height;
          _this.minX=cw/2-imgwidth/2;
          _this.minY=ch/2-imgheight/2;
          _this.maxX=(cw/2-imgwidth/2)+imgwidth;
          _this.maxY=(ch/2-imgheight/2)+imgheight;
          if(_this.activeTab=='2'&&_this.markText!=''){
            const ewidth=document.getElementById('markText').getBoundingClientRect().width;
            const eheight=document.getElementById('markText').getBoundingClientRect().height
            _this.maxX=_this.maxX-ewidth;
            _this.maxY=_this.maxY-eheight;
          }
          if(_this.activeTab=='3'&&_this.markImg!=''){
            const ewidth=document.getElementById('markImg').getBoundingClientRect().width;
            const eheight=document.getElementById('markImg').getBoundingClientRect().height
            _this.maxX=_this.maxX-ewidth;
            _this.maxY=_this.maxY-eheight;
          }
        },500)
      },
      /**
       * @param blob      BLOB对象
       * @param base64    base64字符串
       */
      cutChange({blob, base64}) {
        this.blob = blob;
        this.base64 = base64;
      },
      rotateRight() {
        this.utils.rotate(-90, true)
      },
      rotateLeft() {
        this.utils.rotate(90, true)
      },
      flipY() {
        this.utils.setFlipV(true)
      },
      flipX() {
        this.utils.setFlipH(true)
      },
      onChange() {
      },
      onCancel() {
      },
      //将图片转换为Base64
      getImgToBase64(url, callback) {
        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            img = new Image;
        img.crossOrigin = 'Anonymous';
        img.onload = function () {
          canvas.height = img.height;
          canvas.width = img.width;
          ctx.drawImage(img, 0, 0);
          var dataURL = canvas.toDataURL('image/png');
          callback(dataURL);
          canvas = null;
        };
        img.src = url;
      },
      //将base64转换为文件对象
      dataURLtoFile(dataurl, filename) {
        var arr = dataurl.split(',');
        var mime = arr[0].match(/:(.*?);/)[1];
        var bstr = atob(arr[1]);
        var n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        //转换成file对象
        return new File([u8arr], filename, {type: mime});
        //转换成成blob对象
        //return new Blob([u8arr],{type:mime});
      },
    }
  }
</script>
<style>
    @import "~vue-picture-cut/lib/vue-picture-cut.css";

    .editorView {
        width: 600px;
        height: 500px;
        position: relative;
    }

    .imgeditor {
        display: flex;
        padding: 10px 50px;
        position: relative;
    }

    #myCanvasa {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        z-index: 10000;
        background-color: #fff;
        background-image: url("./transformBg.png");
        background-repeat: repeat;
    }

    .imgstools {
        flex: 1;
        /*margin-left: 40px;*/
    }

    .toolsItem {
        display: flex;
        align-items: center;
        margin-top: 40px;
        flex-flow: wrap;
    }

    .toolsItem > span {
        display: block;
        width: 75px;
        text-align: right;
        margin-right: 10px;
        font-size: 14px;
    }

    .toolsItem > .el-radio-group {
        display: flex;
        flex-flow: wrap;
    }

    .toolsItem + .toolsItem {
        margin-top: 15px;
    }

    .toolsItem > .el-radio-group > label {
        margin: 0 10px 0 0;
        width: 84px;
    }

    .toolsItem > .el-radio-group > .el-radio.is-bordered + .el-radio.is-bordered {
        margin: 0 10px 0 0;
    }
    .markTextView{
        position: absolute;
        border: 1px dashed #000;
        display: block;
        z-index: 20000;
        box-sizing: border-box;
        text-align: left;
    }
    #markImg{
        position: absolute;
        display: block;
        z-index: 20000;
        height: auto;
    }
    .avatar-uploader .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }
    .avatar-uploader .el-upload:hover {
        border-color: #409EFF;
    }
    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 100px;
        height: 100px;
        line-height: 100px !important;
        text-align: center;
    }
    .avatar {
        width: 100px;
        height: 100px;
        display: block;
    }
</style>
